package com.working.libbase.storage

import android.content.SharedPreferences
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.preferencesKey
import com.working.libcommon.exts.doWithTry
import com.working.libcommon.exts.parseJson
import com.working.libcommon.exts.toJson
import com.working.libcommon.util.LogUtils
import com.working.libcommon.util.getType
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import java.lang.reflect.Type
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import kotlin.system.measureTimeMillis
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime


internal inline fun <reified T> SharedPreferences.autoPref(defaultValue: T? = null) =
    SPPreferences<T>(this, getType<T>(), defaultValue)

internal class SPPreferences<T>(
    private val sp: SharedPreferences,
    private val type: Type,
    private val defaultValue: T?
) : ReadWriteProperty<Any, T?> {

    override fun getValue(thisRef: Any, property: KProperty<*>): T? {
        return sp.getString(property.name, null)?.parseJson(type) ?: defaultValue
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
        measureTimeMillis {
            sp.edit().putString(property.name, value.toJson(type)).apply()
        }.let { LogUtils.e("setPreferences $it") }
    }
}